package tk.kolesnikov.algorithms;

import org.apache.commons.math.linear.MatrixUtils;
import org.apache.commons.math.linear.RealMatrix;

/**
 * Created by seko0313 on 16.01.14.
 */
public class MatrixHelper {

    public static void printMatrix(double[][] matrix) {
        int n = matrix.length;
        int m = matrix[0].length;

        System.out.print("[");
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                System.out.print(matrix[i][j]);
                if (j != m - 1)
                    System.out.print(" ");
            }
            if (i != n - 1)
                System.out.println();
        }
        System.out.println("]");
    }

    public static int getAverage(int[][] matrix) {
        int sum = 0;
        for (int x = 0; x < matrix.length; x++)
            for (int y = 0; y < matrix.length; y++) {
                sum += matrix[x][y];
            }
        return sum/(matrix.length*matrix.length);
    }

    public static double getAverage(double[][] matrix) {
        double sum = 0;
        for (int x = 0; x < matrix.length; x++)
            for (int y = 0; y < matrix.length; y++) {
                sum += matrix[x][y];
            }
        return sum/(matrix.length*matrix.length);
    }

    public static int[][] getAverageMask(int[][] matrix, int average) {
        int[][] result = new int[matrix.length][matrix.length];

        for (int x = 0; x < matrix.length; x++)
            for (int y = 0; y < matrix.length; y++) {
                if (matrix[x][y] < average)
                    result[x][y] = 0;
                else
                    result[x][y] = 1;
            }
        return result;
    }

    public static int[][] getAverageMask(double[][] matrix, double average) {
        int[][] result = new int[matrix.length][matrix.length];

        for (int x = 0; x < matrix.length; x++)
            for (int y = 0; y < matrix.length; y++) {
                if (matrix[x][y] < average)
                    result[x][y] = 0;
                else
                    result[x][y] = 1;
            }
        return result;
    }

    public static double[][] multiply(double[][] a, double[][] b) {
        RealMatrix amatrix = MatrixUtils.createRealMatrix(a);
        RealMatrix bmatrix = MatrixUtils.createRealMatrix(b);
        return amatrix.multiply(bmatrix).getData();
    }

    public static int[][] multiply(int[][] a, int[][] b) {
        return doubleMatrixToIntMatrix(multiply(intMatrixToDoubleMatrix(a), intMatrixToDoubleMatrix(b)));
    }

    public static int[][] doubleMatrixToIntMatrix(double[][] matrix) {
        int[][] result = new int[matrix.length][matrix[0].length];
        for (int x = 0; x < matrix.length; x++)
            for (int y = 0; y < matrix[0].length; y++)
                result[x][y] = (int) matrix[x][y];
        return result;
    }

    public static double[][] intMatrixToDoubleMatrix(int[][] matrix) {
        double[][] result = new double[matrix.length][matrix[0].length];
        for (int x = 0; x < matrix.length; x++)
            for (int y = 0; y < matrix[0].length; y++)
                result[x][y] = matrix[x][y];
        return result;
    }

    public static double[][] reduceMatrix(double[][] dctResult, int newDimension) {
        double[][] res = new double[newDimension][newDimension];
        for (int x = 0; x < newDimension; x++)
            for (int y = 0; y < newDimension; y++)
                res[x][y] = dctResult[x][y];
        return res;
    }
}
